package edu.ustb.aur.rightpackage;

import java.util.HashMap;

import edu.ustb.aur.myenum.OperateEnum;
import edu.ustb.aur.utils.PercentageOperate;

/**
 * @author 具体实现在子类中 double类型比较大小使用Double.doubleToLongBits()函数 double类型加减使用BigDecimal对象
 */
public abstract class AbstractRight {

    // 两个变量
    /**
     * 权利所有人和权利占比的对应 HashMap<userAddress, percentage>
     */
    public HashMap<String, Double> rightMap;

    /**
     * 权利是否可分
     */
    public boolean isSpilt;

    // isSpilt的set和get方法
    /**
     * 设置是否可分属性 使用权可分
     * 
     * @param isSpilt
     *            true or false
     */
    public void setIsSpilt(boolean isSpilt) {
        this.isSpilt = isSpilt;
    }

    /**
     * 得到属性是否可分
     *
     * @return true or false
     */
    public boolean getIsSpilt() {
        return this.isSpilt;
    }

    // 三大方法
    /**
     * 权利初始化
     *
     * @param userAddress
     *            用户链上地址，唯一索引
     * @param percentage
     *            百分比
     */
    public abstract void initRight(String userAddress, double percentage);

    /**
     * 权利转移
     *
     * @param from
     *            转移者
     * @param to
     *            接收者
     * @param percentage
     *            百分比
     */
    public abstract void transferRight(String from, String to, double percentage);

    /**
     * 权利注销
     *
     * @param userAddress
     *            用户链上地址，唯一索引
     * @param percentage
     *            百分比
     */
    public abstract void deleteRight(String userAddress, double percentage);

    // 构造方法
    /**
     * 默认构造函数
     */
    public AbstractRight() {

        this.isSpilt = false;
        this.rightMap = new HashMap<>();
    }

    /**
     * 带参构造函数
     * 
     * @param rightMap
     *            人与权占比对应map
     * @param isSplit
     *            是否可分
     */
    public AbstractRight(HashMap<String, Double> rightMap, boolean isSplit) {

        this.isSpilt = isSplit;
        // 百分比总和
        double total = PercentageOperate.total(rightMap);
        if (PercentageOperate.equal(total, 1.0)) {
            // 一定要调用putAll方法对传入rightMap深度拷贝，不然就会出现四项基本权利都指向同一个rightmap的问题
            this.rightMap = new HashMap<>();
            this.rightMap.putAll(rightMap);
        } else {
            System.out.println("创建失败,权力划分超过限定值！！！");
        }
    }

    /**
     * 判断权利初始化、转移、删除时，权利百分比是否合理(不能大于1，不能小于0)
     * 
     * @param rightMap
     *            用户名和权利百分比的映射
     * @param userAddress
     *            用户链上地址，唯一索引
     * @param operator
     *            操作
     * @param percentage
     *            百分比
     * @return true or false
     */
    public boolean ifLogic(HashMap<String, Double> rightMap, String userAddress, OperateEnum operator, double percentage) {

        // 百分比总和
        double total = PercentageOperate.total(rightMap);

        switch (operator) {
            case ADD_OPERATE:
                // 判断用户地址是否存在
                if (rightMap.containsKey(userAddress)) {
                    System.out.println("已存在该用户，操作符类别错误！！！");
                    return false;
                }
                // 判断是否大于1
                double result1 = PercentageOperate.add(total,percentage);
                if (PercentageOperate.compare(result1, 1.0)) {
                    System.out.println("权利百分比总和大于1！！！");
                    return false;
                } else {
                    rightMap.put(userAddress, percentage);
                    return true;
                }
            case UPDATE_OPERATE:
                if (!rightMap.containsKey(userAddress)) {
                    System.out.println("不存在该用户，操作符类别错误！！！");
                    return false;
                }
                // 未更新的权利百分比rightMap.get(userAddress)
                // 要更新的权利百分比percentage
                // total - 未更新 + 要更新 = result
                double result2 = PercentageOperate.add(PercentageOperate.subtract(total,rightMap.get(userAddress)),percentage);
                // result大于1和小于1的判断
                if (PercentageOperate.compare(result2,1.0) || PercentageOperate.compare(1.0,result2)) {
                    return false;
                } else {
                    rightMap.replace(userAddress, percentage);
                    return true;
                }
            case DELETE_OPERATE:
                // 用户名不存在相当于删除完成了
                if (!rightMap.containsKey(userAddress)) {
                    System.out.println("不存在该用户，无效操作！！！");
                    return true;
                }
                // 删除就是删除所有，传入了percentage要等于原本的权利百分比，不然就是更新操作了
                if (PercentageOperate.notEqual(percentage,rightMap.get(userAddress))) {
                    System.out.println("权利百分比删除不对等，操作符类别错误！！！");
                    return false;
                }
                // total - percentage
                double result3 = PercentageOperate.subtract(total,percentage);
                if (PercentageOperate.compare(0.0, result3)) {
                    return false;
                } else {
                    rightMap.remove(userAddress, percentage);
                    return true;
                }
            default:
                return false;
        }
    }
}
